package cz.schovjan.mte_proj.service;

import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.util.Log;
import cz.schovjan.mte_proj.Constant;
import cz.schovjan.mte_proj.dto.LyricResult;
import cz.schovjan.mte_proj.dto.VideoEntry;

public class SearcherImpl implements Searcher {

    /** odkaz pro stazeni textu dle interpreta a nazvu pisne */
    private static String SEARCH_LYRIC_DIRECT = "http://api.chartlyrics.com/apiv1.asmx/SearchLyricDirect?artist={0}&song={1}";
    /** odkaz pro nalezeni pisni a jejich interpretu dle casti textu pisne */
    private static String SEARCH_LYRIC_TEXT = "http://api.chartlyrics.com/apiv1.asmx/SearchLyricText?lyricText={0}";
    /** odkaz pro stazeni textu pisne dle jejiho id a kontrolniho souctu */
    private static String GET_LYRIC = "http://api.chartlyrics.com/apiv1.asmx/GetLyric?lyricId={0}&lyricCheckSum={1}";
    /** odkaz pro vyhledani pisne dle interpreta a nazvu na youtube */
    private static String SEARCH_VIDEOS = "http://gdata.youtube.com/feeds/api/videos?q={0}&fields=entry(title,link[@rel=''alternate''])&max-results=15";


    @Override
    public List<LyricResult> byArtistSong(String artist, String song) throws Exception {
	List<LyricResult> result = new ArrayList<LyricResult>();
	Document doc = getDoc(correctUrl(SEARCH_LYRIC_DIRECT, new Object[] { artist, song }));
	// prohledani vsech zaznamu a parsovani dat
	LyricResult l = new LyricResult();
	l.setChecksum(doc.getElementsByTagName("LyricChecksum").item(0).getTextContent());
	l.setLyricId(doc.getElementsByTagName("LyricId").item(0).getTextContent());
	l.setArtist(doc.getElementsByTagName("LyricArtist").item(0).getTextContent());
	l.setSong(doc.getElementsByTagName("LyricSong").item(0).getTextContent());
	l.setText(doc.getElementsByTagName("Lyric").item(0).getTextContent());
	result.add(l);
	return result;
    }


    @Override
    public List<LyricResult> byTextContain(String text) throws Exception {
	List<LyricResult> result = new ArrayList<LyricResult>();
	Document doc = getDoc(correctUrl(SEARCH_LYRIC_TEXT, new Object[] { text }));
	// prohledani vsech zaznamu a parsovani dat
	NodeList nl = doc.getElementsByTagName("SearchLyricResult");
	for (int i = 0; i < nl.getLength() - 1; i++) {
	    Element el = (Element) nl.item(i);
	    if (!el.hasChildNodes()) {
		continue;
	    }
	    LyricResult l = new LyricResult();
	    l.setChecksum(el.getElementsByTagName("LyricChecksum").item(0).getTextContent());
	    l.setLyricId(el.getElementsByTagName("LyricId").item(0).getTextContent());
	    l.setArtist(el.getElementsByTagName("Artist").item(0).getTextContent());
	    l.setSong(el.getElementsByTagName("Song").item(0).getTextContent());
	    result.add(l);
	}
	return result;
    }


    private Document getDoc(String address) throws Exception {
	URL url = new URL(address);
	DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
	DocumentBuilder db = dbf.newDocumentBuilder();
	InputStream is = url.openStream();
	// xml dokument
	Document doc = (Document) db.parse(is);
	is.close();
	return doc;
    }


    private String correctUrl(String url, Object[] params) throws UnsupportedEncodingException {
	Object[] os = new Object[params.length];
	for (int i = 0; i < params.length; i++) {
	    if (params[i] instanceof String) {
		os[i] = URLEncoder.encode((String) params[i], "UTF-8");
	    } else {
		os[i] = params[i];
	    }
	}
	url = MessageFormat.format(url, (Object[]) os);
	Log.i(Constant.TAG, url);
	return url;
    }


    @Override
    public void loadLyric(LyricResult l) throws Exception {
	Document doc = getDoc(correctUrl(GET_LYRIC, new Object[] { l.getLyricId(), l.getChecksum() }));
	l.setText(doc.getElementsByTagName("Lyric").item(0).getTextContent());
    }


    @Override
    public List<VideoEntry> video(LyricResult l) throws Exception {
	List<VideoEntry> result = new ArrayList<VideoEntry>();
	String query = l.getArtist() + " " + l.getSong();
	Document doc = getDoc(correctUrl(SEARCH_VIDEOS, new Object[] { query }));
	NodeList nl = doc.getElementsByTagName("entry");
	for (int i = 0; i < nl.getLength() - 1; i++) {
	    Element el = (Element) nl.item(i);
	    if (!el.hasChildNodes()) {
		continue;
	    }
	    VideoEntry ve = new VideoEntry();
	    ve.setTitle(el.getElementsByTagName("title").item(0).getTextContent());
	    ve.setUrl(el.getElementsByTagName("link").item(0).getAttributes().getNamedItem("href").getTextContent());
	    result.add(ve);
	}
	return result;
    }
}
